import React, { useEffect, useState } from 'react'
// 引入路由组件
import Home from '../../views/NewsSandBox/Home'
import UserList from "../../views/NewsSandBox/UserList"
import RoleList from '../../views/NewsSandBox/RightManage/RoleList'
import RightList from '../../views/NewsSandBox/RightManage/RightList'
import NoPermission from '../../views/NewsSandBox/NoPermission'
import NewsAdd from '../../views/NewsSandBox/News-manage/NewsAdd'
import NewsDraft from '../../views/NewsSandBox/News-manage/NewsDraft'
import NewsPreview from '../../views/NewsSandBox/News-manage/NewsPreview'
import NewsUpdate from '../../views/NewsSandBox/News-manage/NewsUpdate'
import NewsCategory from '../../views/NewsSandBox/News-manage/NewsCategory'
import Audit from '../../views/NewsSandBox/Audit-manage/Audit'
import AuditList from '../../views/NewsSandBox/Audit-manage/AuditList'
import Unpublished from '../../views/NewsSandBox/Publish-manage/Unpublished'
import Published from '../../views/NewsSandBox/Publish-manage/Published'
import Sunset from '../../views/NewsSandBox/Publish-manage/Sunset'
import { Spin } from 'antd'
import { Switch, Route, Redirect } from "react-router-dom"
import axios from 'axios'
import { connect } from 'react-redux'

// 这个对象中存储着路由路径和路由组件的匹配关系
const LocalRouterList = {
    // 属性名是路由路径，属性值是路由路径对应的要显示的路由组件
    "/home": Home,
    "/user-manage/list": UserList,
    "/right-manage/role/list": RoleList,
    "/right-manage/right/list": RightList,
    "/news-manage/add": NewsAdd,
    "/news-manage/draft": NewsDraft,
    "/news-manage/category": NewsCategory,
    "/news-manage/preview/:id": NewsPreview,
    "/news-manage/update/:id": NewsUpdate,
    "/audit-manage/audit": Audit,
    "/audit-manage/list": AuditList,
    "/publish-manage/unpublished": Unpublished,
    "/publish-manage/published": Published,
    "/publish-manage/sunset": Sunset
}

function NewsRouter(props) {

    // 存储用户能够访问的路由路径
    const [BackRouterList, setBackRouterList] = useState([])

    // 从本地存储中获取token值，并且 role 从 token 中解构出来，再将 rights用户权限 从 role 中解构出来
    const { role: { rights } } = JSON.parse(localStorage.getItem("token"))

    // 下面两个函数用于判断用户是否拥有访问指定路由组件的权力
    const checkRouter = (item)=>{
        // item.key 是一个路由路径
        return LocalRouterList[item.key] && (item.pagepermisson || item.routepermisson)
    }
    const checkUserPermission = (item)=>{
        // rights 存储的是当前用户可以访问的路由组件的路由路径
        // 检测当前用户是否有权限访问当前路由路径对应的路由组件
        return rights.includes(item.key)
    }

    useEffect(() => {
        // Promise.all方法接受一个数组作为参数，这个数组装的都是Promise函数
        // Promise.all方法会等到数组中的所有Promise函数都返回一个成功状态的时候，再返回自身的成功状态的Promise函数
        Promise.all([
            // 这里是只有下面两个请求都执行完毕，并且都返回一个成功状态的Promise函数时候，才会返回Promise.all自身的成功状态的Promise，从而才能够执行下面的then方法
            axios.get('http://localhost:5000/rights'),
            axios.get('http://localhost:5000/children'),
        ]).then(res => {
            // 这里的res接收的是上面两个axios请求成功返回的结果
            setBackRouterList([...res[0].data, ...res[1].data])
        })
    },[])

    return (
        <div>
            {/* 这个antd组件有一种加载中的效果 */}
            {/* spinning 决定这个组件是否显示，如果值为true，那么就显示，反之则隐藏 */}
            <Spin size="large" spinning={props.isLoading}>
                {/* 开启路由的严格匹配 */}
                <Switch>
                    {/* 下面这些路由路径在当前这个项目中相当于二级路由 */}

                    {/* 手动创建路由组件 */}
                    {/* <Route path="/home" component={Home} />
                    <Route path="/user-manage/list" component={UserList} />
                    <Route path="/right-manage/role/List" component={RoleList} />
                    <Route path="/right-manage/right/List" component={RightList} /> */}

                    {/* 动态生成路由组件 */}
                    {
                            BackRouterList.map((item)=>{
                                // 判断用户是否有访问该路由组件的权限
                                if(checkRouter(item) && checkUserPermission(item)){
                                    return <Route path={item.key} key={item.key} component={LocalRouterList[item.key]} exact/>
                                }
                                return null
                            })
                    }

                    {/* 重定向 当访问根路径 / 时，会自动重定向到 /home 路径页面 exact是使得这一条路由规则开启精确匹配 */}
                    <Redirect from="/" to="/home" exact />

                    {/* 如果当前用户可以访问的路由不为0(这是为了防止网速过慢的时候显示下面这个路由组件)，并且当路由路径不为以上任何一种情况的时候，显示对应的路由组件 */}
                    {
                        BackRouterList.length>0 && <Route path="*" component={NoPermission} />
                    }
                </Switch>
            </Spin>
        </div>
    )
}

// connect 函数是 React Redux 库提供的用于创建和连接容器组件的函数。它接收两个参数：mapStateToProps 和 mapDispatchToProps。通过 connect 函数，组件可以访问 Redux Store 中的状态并触发对应的 Action
/* 
    connect(
      mapStateToProps     // mapStateToProps 用于将 Redux Store 中的状态映射到当前组件的属性上
      mapDispatchToProps
    )(被包装的组件)
*/
// mapStateToProps接收一个reducer作为参数对象，下面是将 LoadingReducer 中的 isLoading 解构出来
const mapStateTopProps = ({ LoadingReducer: { isLoading } }) => {
    return {
        // 将 isLoading 返回出去，这样当前这个组件就可以通过 props 获取到这个 isLoading 属性
        isLoading
    }
}
export default connect(mapStateTopProps)(NewsRouter)